package com.hurl.waguji.biz.download;

import java.util.Date;

import com.hurl.library.spider.SpiderException;
import com.hurl.library.spider.SpiderListener;
import com.hurl.library.spider.UrlPattern;
import com.hurl.library.util.DateUtils;
import com.hurl.waguji.base.DateService;
import com.hurl.waguji.base.dao.HibernateDao;
import com.hurl.waguji.base.dao.HibernateService;
import com.hurl.waguji.base.dataprocess.ProcessHelper;
import com.hurl.waguji.base.dataprocess.ProcessResult;
import com.hurl.waguji.base.dataprocess.ProcessParams;

abstract class BaseDownloadProcessor implements SpiderListener {

	private ProcessResult result;
	private BOSaver saver;
	protected DownloadContext context;
	protected DownloadIdentifier identifier;
	public BaseDownloadProcessor(ProcessParams params, DownloadIdentifier identifier){
		context = new DownloadContext(params);
		this.identifier=identifier;
		HibernateDao dao = HibernateService.getDao();
		context.setDao(dao);
		saver = new BOSaver(context);
		result = new ProcessResult(this.identifier);
	}

	public abstract UrlPattern getUrlPattern();
	
	public abstract Date getRq();
	
	public ProcessResult getDownloadResult(){
		return result;
	}
	
	/**
	 * 校验当前时间是否为交易日休市后时间。如果不是则抛出异常。
	 * @param tradingTime
	 * @throws SpiderException
	 */
	protected void validateNowAfterTradingTime(Date tradingTime) throws SpiderException{
		if(!DateService.isNowAfterTradingTime(tradingTime)){
			throw new SpiderException("只能在交易日("+DateUtils.formatDate(tradingTime, DateUtils.FORMAT_DATE_CN)+")当天休市后下载！");
		}
	}
	/**
	 * 校验某日的数据是否已经下载过，如果下载过，抛出异常。
	 * @param rq
	 * @throws SpiderException
	 */
	protected void validateAlreadyDownloaded(Date rq) throws SpiderException{
		if(isAlreadyDownloaded()){
			throw new SpiderException(DateUtils.formatDate(rq, DateUtils.FORMAT_DATE_CN) +
			"的数据已经下载过！");
		}
	}
	protected boolean isAlreadyDownloaded(){
		return ProcessHelper.isAlreadyProcessed(this.identifier.getId(), this.getRq(), this.context.getDao());
	}
	@Override
	public void startup() throws SpiderException {
		result.setStartTime(new Date());
		try{
			this.validate();
		}catch(Throwable t){
			result.setCount(0);
			result.setEndTime(new Date());
			result.setSuccess(false);
			result.setRq(this.getRq());
			result.setError(t);
			ProcessHelper.saveProcessResult(result, context.getDao());
			context.getDao().flush();
			throw new SpiderException("验证不通过，停止下载！",t);
		}
	}

	@Override
	public boolean beforeDownload(String url) throws SpiderException {
		if(context.isStopWithError()){
			throw new SpiderException(context.getError().getMessage());
		}
		return true;
	}

	@Override
	public void downloadSuccess(String url, String html) throws SpiderException {
		this.convertHTML2BO(url,html,saver);
	}

	@Override
	public void teardown(boolean success, Throwable t) throws SpiderException {
		saver.finished();
		this.shutdown(success, t);
		result.setCount(saver.getTotalCount());
		result.setEndTime(new Date());
		result.setSuccess(success);
		result.setRq(this.getRq());
		result.setError(t);
		
		ProcessHelper.saveProcessResult(result, context.getDao());
		context.getDao().flush();
	}

	public abstract void validate()throws Throwable;
	
	public abstract void convertHTML2BO(String url, String html, BOSaver saver);

	public abstract void shutdown(boolean success, Throwable t);
}
